package com.m1.tzolkin.model.temples;

import java.util.HashMap;
import java.util.Map;

import com.m1.tzolkin.model.Action;
import com.m1.tzolkin.model.Season;
import com.m1.tzolkin.model.TZResource;
import com.m1.tzolkin.model.board.ITZBoard;
import com.m1.tzolkin.model.exceptions.NoAvailableSkullException;
import com.m1.tzolkin.model.players.ITZPlayer;

public enum TempleEnum implements ITemple {
	
	CHAAC("Chaac", 7) {
		@Override
		public int getTopPoints(int time) {
			if (time < 0) {
				throw new IllegalArgumentException();
			}
			switch (time) {
			case 0: return 6;
			case 1: return 2;
			default: return 0;
			}
		}
		@Override
		public Action[] getActions(Season s) {
			if (super.getActions(s) == null) {
				actions.get(this).put(Season.MIDDLE_ERA, new Action[] {
					null,
					null,
					new TempleActionResource(TZResource.STONE, 1),
					null,
					new TempleActionResource(TZResource.STONE, 1),
					null,
					null
				});
				actions.get(this).put(Season.END_ERA, new Action[] {
					new TempleActionVictoryPoints(-1),
					null,
					new TempleActionVictoryPoints(2),
					new TempleActionVictoryPoints(4),
					new TempleActionVictoryPoints(6),
					new TempleActionVictoryPoints(7),
					new TempleActionVictoryPoints(8)
				});
			}
			return actions.get(this).get(s);
		}
	},
	QUETZALCOATL("Quetzalcoatl", 9) {
		@Override
		public int getTopPoints(int time) {
			if (time < 0) {
				throw new IllegalArgumentException();
			}
			switch (time) {
			case 0: return 2;
			case 1: return 6;
			default: return 0;
			}
		}
		@Override
		public Action[] getActions(Season s) {
			if (super.getActions(s) == null) {
				actions.get(this).put(Season.MIDDLE_ERA, new Action[] {
					null,
					null,
					null,
					new TempleActionResource(TZResource.GOLD, 1),
					null,
					new TempleActionResource(TZResource.GOLD, 1),
					null,
					null,
					null
				});
				actions.get(this).put(Season.END_ERA, new Action[] {
					new TempleActionVictoryPoints(-2),
					null,
					new TempleActionVictoryPoints(1),
					new TempleActionVictoryPoints(2),
					new TempleActionVictoryPoints(4),
					new TempleActionVictoryPoints(6),
					new TempleActionVictoryPoints(9),
					new TempleActionVictoryPoints(12),
					new TempleActionVictoryPoints(13)
				});
			}
			return actions.get(this).get(s);
		}
	},
	KUKULCAN("Kukulcan", 8) {
		@Override
		public int getTopPoints(int time) {
			if (time < 0) {
				throw new IllegalArgumentException();
			}
			switch (time) {
			case 0: return 4;
			case 1: return 4;
			default: return 0;
			}
		}
		@Override
		public Action[] getActions(Season s) {
			if (super.getActions(s) == null) {
				actions.get(this).put(Season.MIDDLE_ERA, new Action[] {
					null,
					null,
					new TempleActionResource(TZResource.WOOD, 1),
					null,
					new TempleActionResource(TZResource.WOOD, 1),
					new Action() {
						/**
						 * 
						 */
						private static final long serialVersionUID = 4585479197716717247L;

						public void doAction(ITZBoard b, ITZPlayer p) {
							try {
								b.getBank().takeSkull();
								p.getWallet().addSkull();
								b.getLog().addSentence(new String[] {
									p.getName(), "GET", "1", "SKULL"
								});
							} catch (NoAvailableSkullException e) {
								// Rien
							}
						}
					},
					null,
					null
				});
				actions.get(this).put(Season.END_ERA, new Action[] {
					new TempleActionVictoryPoints(-3),
					null,
					new TempleActionVictoryPoints(1),
					new TempleActionVictoryPoints(3),
					new TempleActionVictoryPoints(5),
					new TempleActionVictoryPoints(7),
					new TempleActionVictoryPoints(9),
					new TempleActionVictoryPoints(10)
				});
			}
			return actions.get(this).get(s);
		}
	};
	
	private static class TempleActionResource extends Action {
		/**
		 * 
		 */
		private static final long serialVersionUID = -4107666502680796808L;
		private final TZResource resource;
		private final int qty;
		TempleActionResource(TZResource r, int qty) {
			resource = r;
			this.qty = qty;
		}
		public void doAction(ITZBoard b, ITZPlayer p) {
			p.getWallet().addResource(resource, qty);
			b.getLog().addSentence(new String[] {
				p.getName(), "EARN", "" + qty, resource.toString()
			});
		}
	}
	
	private static class TempleActionVictoryPoints extends Action {
		/**
		 * 
		 */
		private static final long serialVersionUID = 8233614562313528041L;
		private final int qty;
		TempleActionVictoryPoints(int qty) {
			this.qty = qty;
		}
		public void doAction(ITZBoard b, ITZPlayer p) {
			p.addScore(qty);
			b.getLog().addSentence(new String[] {
				p.getName(), "GET", "" + qty, "POINT" + (qty > 1 ? "S" : "")
			});
		}
	}
	
	// ATTRIBUTS
	
	private final String name;
	private static final Map<TempleEnum, Map<Season, Action[]>> actions =
			new HashMap<TempleEnum, Map<Season, Action[]>>();
	private final int height;
	
	// CONSTRUCTEUR
	
	private TempleEnum(String name, int n) {
		if (name == null || name.trim().equals("") || n <= 0) {
			throw new IllegalArgumentException();
		}
		this.name = name;
		this.height = n;
	}
	
	// REQUETES

	@Override
	public String getName() {
		return name;
	}

	@Override
	public int getHeight() {
		return height;
	}

	@Override
	public Action[] getActions(Season s) {
		if (s == null) {
			throw new IllegalArgumentException();
		}
		if (actions.get(this) == null) {
			actions.put(this, new HashMap<Season, Action[]>());
		}
		return actions.get(this).get(s);
	}
	
}
